<?php

/**
 * @brief Klasa kontrolera commodities z modułu "admin"
 * 
 * Kontroler umożliwiający zarządzanie towarami oraz terminami dostaw towarów. 
 *
 */
class Admin_CommoditiesController extends Zend_Controller_Action
{

    protected $_user = null; /*!< Pole na dane użytkownia uzyskiwane z Zend_Auth */

    /**
     * @brief Standardowa metoda, której wykonanie poprzedza działanie akcji.
     * 
     * Przekazywany jest do niej widok nagłówka, pobierane są
     * wiadomości z flashMessengera oraz sprawdzane jest czy
     * użytkownik jest  zalogowany i uprawniony do dostępu do
     * akcji kontrolera.  
     * 
     */
    public function preDispatch()
    {
        $this->view->render('index/_headbox.phtml');
        $this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
        $this->view->messages = $this->_flashMessenger->getMessages();
        
        $auth = Zend_Auth::getInstance();
        if($auth->hasIdentity()){
            $this->_user = $auth->getIdentity();
        } else {
            $this->_helper->flashMessenger->addMessage("warning/Zaloguj się!");
            $this->_helper->redirector('login','auth','default');
        }
        
        $user = $auth->getIdentity();
        if($user->role != 'admin'){
            $this->_helper->flashMessenger->addMessage("warning/Nie masz wymaganych uprawnień!");
            $this->_helper->redirector('index','mymca','default'); 
        }
    }

    /**
     * @brief Akcja index 
     * 
     * Akcja służy jako strona główna kontrolera.
     * W jej widoku wyświetlane są proste statystyki:
     * - liczba towarów
     * - liczba kategorii
     * - liczba aktualnych globalnych terminów dostaw
     */
    public function indexAction()
    {
        $categoryMapper = new Application_Model_CategoryMapper();
        $typeMapper = new Application_Model_CommodityTypeMapper();
        $periodMapper= new Application_Model_CalendarPeriodMapper();
        
        $data = array(
            'cats'   => $categoryMapper->count(),
            'types'  =>$typeMapper->count(),
            'periods'=> $periodMapper->count('endTime > now() and periodType = "global"'),
        );
        
        $this->view->data = $data;
    }

    /**
     * @brief Akcja types 
     * 
     * Akcja wyświetla ekran słownika towarów umożliwiający zarządzanie listą 
     * dostępnych na towarów. Towary można rozdzielać na kategorie za pomocą 
     * parametru 'cat'. Sama w sobie umożliwia tylko tworzenie nowego terminu w 
     * słowniku.
     *  
     */
    public function typesAction()
    {
        $form = new Application_Form_AddType();
        $mapper = new Application_Model_CommodityTypeMapper();
        $this->view->typeForm = $form;
        
        $request = $this->getRequest();
        //dodawanie nowego typu towaru
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                $type = new Application_Model_CommodityType($form->getValues());
                $mapper->save($type);
                $this->view->messages[] = 'success/Dodano termin do słownika';
               
            }
        }
        //określanie co ma być wyświetlone
        $page = $request->getParam('page');
        if(!isset($page)) $page = 1; 
        
        $cat = $request->getParam('cat');
        if(!isset($cat))
        {
            $types = $mapper->fetchAll(); 
        } else {
            $types = $mapper->fetchAll("Category_id = $cat"); 
            $catMpper = new Application_Model_CategoryMapper();
            $this->view->catName = $catMpper->find($cat)->getName();
        }
        
        $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($types));
        $paginator->setCurrentPageNumber($page);
        $paginator->setItemCountPerPage(20);     
        $this->view->types = $paginator;
        
        
        
    }

    /**
     * @brief Akcja categories 
     * 
     * Akcja wyświetlająca ekran kategorii towarów, z którego można nimi zarządzać.
     * Z listy kategorii można przejść do ekranu słownika towarów. 
     * Po wybraniu jednej z kategorii zostanie wyświetlona lista wszystkich towarów 
     * z nią powiązanych. Sama w sobie udostępnia tylko tworzenie nowej kategorii.
     * 
     */
    public function categoriesAction()
    {
        
        $form = new Application_Form_AddCategory();
        $this->view->form = $form;
        
        $mapper = new Application_Model_CategoryMapper();
        
        $request = $this->getRequest();
        
        $this->view->categories = $mapper->fetchAll();
        // dodawanie nowej kategorii
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                
                $category = new Application_Model_Category($form->getValues());
                $mapper->save($category);
                $this->view->messages[] = 'success/Dodano kategorię';
            }
        }
        
        $this->view->categories = $mapper->fetchAll();
    }
    
    /**
     * @brief Akcja periods
     * 
     * Akcja wyświetlająca ekran zarządzania globalnymi terminami dostaw. Terminy
     * tego typu są dostępne dla wszystkich użytkowników systemu. Akcja odpowiada 
     * tylko za wyświetlanie listy takich terminów i ich tworzenie. 
     * 
     */
    public function periodsAction()
    {
        
        $form= new Application_Form_AddPeriod();
        $this->view->form = $form;
        $request = $this->getRequest();
        $mapper = new Application_Model_CalendarPeriodMapper();
        //tworzenie nowego terminu dostaw
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                $period = new Application_Model_CalendarPeriod($form->getValues());
                $startTime = new Zend_Date($period->getStartTime());
                $endTime = new Zend_Date($period->getEndTime());
                //zapisywane są tylko terminy z poprawnymi datami
                if($startTime->isEarlier($endTime) && ($startTime->isLater(Zend_Date::now()))){
                    $period->setStartTime($startTime->getIso());
                    $period->setEndTime($endTime->getIso());
                    $period->setPeriodType('global');
                    $mapper->save($period);
                    $this->view->messages[] = 'success/Dodano nowy okres';
                } else {
                    $this->view->messages[] = 'error/Wprowadzono błędne daty';
                }
                
            }
        }
        $this->view->periods = $mapper->fetchAll("periodType = 'global'");
    }


    /**
     * @brief Akcja delete period
     * 
     * Akcja usuwania terminu dostaw.
     * Możliwe jest usunięcie tylko nieużywanych terminów globalnych.
     * Akcja nie posiada widoku.
     */
    public function deletePeriodAction()
    {
        $request = $this->getRequest();
        $mapper = new Application_Model_CalendarPeriodMapper();
        if(array_key_exists('id', $request->getParams()) && ($mapper->delete($request->getParam('id'), NULL, TRUE))){
            
            $this->_helper->_flashMessenger->addMessage('success/Usunięto okres dostaw '.$request->getParam('id'));

        } else {
            $this->_helper->_flashMessenger->addMessage('error/Niepoprawny identyfikator okresu dostaw');
        }
        $this->_helper->_redirector('periods');
    }

    /**
     * @brief Akcja edit period
     * 
     * Akcja edycji terminów dostaw.
     * Akcja umożliwa edycję globalnych terminów dostaw. Formularz w widoku 
     * posiada wypełnione pola w sposób jaki poprzednio zostały one wypełnione. 
     */
    public function editPeriodAction()
    {
        $form = new Application_Form_AddPeriod();
        $this->view->form = $form;
        $mapper = new Application_Model_CalendarPeriodMapper();
        $request = $this->getRequest();
        //sprawdzanie wprowadzonego identyfikatora
        if(array_key_exists('id', $request->getParams())){
            $period  = $mapper->find($request->getParam('id'));
            if(!isset($period)){
                $this->_helper->_flashMessenger->addMessage('error/Niepoprawny identyfikator okresu dostaw');
                $this->_helper->_redirector('periods');
            } elseif ($period->getPeriodType() != 'global') {
                $this->_helper->_flashMessenger->addMessage('error/Można edytować tylko globalnie okresy dostaw!');
                
            }
            //usupełnianie danych
            $values = array(
                'startTime' => $this->changeDateFormat($period->getStartTime()),
                'endTime'   => $this->changeDateFormat($period->getEndTime()),
                'name'      => $period->getName(),
            );
            
            $form->populate($values);
            //edycja starego towaru
            if($request->isPost()){
                if($form->isValid($request->getPost())){
                    $period->setName($request->getParam('name'));
                    $startTime = new Zend_Date($request->getParam('startTime'));
                    $endTime = new Zend_Date($request->getParam('endTime'));
                    if($startTime->isEarlier($endTime) && ($startTime->isLater(Zend_Date::now()))){
                    $period->setStartTime($startTime->getIso());
                    $period->setEndTime($endTime->getIso());
                    $mapper->save($period);
                    $this->_helper->_flashMessenger->addMessage('success/Udało się zmienić okres dostaw');
                    $this->_helper->_redirector('periods');
                    } else {
                        $this->view->messages[] = 'error/Wprowadzono błędne daty.';
                    }

                }
            }
        }
        
    }
    
    /**
     * @brief Akcja edit types
     * 
     * Akcja edycji terminu w słowniku towarów.
     * Umożliwia zmianę nazwy, kategorii i opisu rodzaju towaru. 
     * Informacje w formularzu edycji są uzupełniane zgodnie z wcześniej 
     * wprowadzonymi danymi.
     * 
     */
    public function editTypesAction()
    {
        $id = $this->getRequest()->getParam('id');
        $request = $this->getRequest();
        $form = new Application_Form_AddType();
        $this->view->form = $form;
        //uzupełnianie formularza
        if(isset ( $id )){
            $mapper = new Application_Model_CommodityTypeMapper();
            $type = $mapper->find($id);
            $data = array(
            'Category_id'   => $type->getCategory_id(),
            'name'          => $type->getName(),
            'description'   => $type->getDescription(),
            'CommodityType_id' => $type->getCommodityType_id(),
            'categoryName' => $type->getCategoryName(),
             );
            $form->populate($data);
            $this->view->data = $data;
            if($type != NULL ){
                if($request->isPost()){
                    if($form->isValid($request->getPost())){
                        $type->setOptions($form->getValues());
                        $mapper->save($type);
                        $this->_helper->_flashMessenger->addMessage('success/Zmieniono szczegóły terminu słownikowowego');
                        $this->_helper->_redirector('types'); 
                    }
                }
            } else {
                $this->_helper->_flashMessenger->addMessage('error/Nie znaleziono terminu o podanym id');
                $this->_helper->_redirector('types');      
            }
        } else {
            $this->_helper->_flashMessenger->addMessage('error/Nie wskazano terminu do edycji ');
            $this->_helper->_redirector('types');
        }
        
        
        
    }
    
    /**
     * @brief Akcja delete types
     * 
     * Akcja usuwająca typ towaru
     * Usuwane mogą być tylko nowe wpisy, które nie zostały jeszcze wykorzystane
     * przez użytkowników. Akcja nie posiada własnego widoku.
     * 
     */
    public function deleteTypeAction()
    {
        $id = $this->getRequest()->getParam('id');
        if(isset ( $id )){
            $commodityMapper = new Application_Model_CommodityMapper();
            
            if($commodityMapper->count('CommodityType_id = "'.$id.'"') == 0 ){
                $mapper = new Application_Model_CommodityTypeMapper();
                $mapper->delete($id);
                $this->_helper->_flashMessenger->addMessage('success/Usunięto podany termin słownikowy');
            } else {
                $this->_helper->_flashMessenger->addMessage('error/Podany termin słownikowy jest już w użyciu');
            }
        } else {
            $this->_helper->_flashMessenger->addMessage('error/Nie wskazano terminu słownikowego do usunięcia ');
        }
        $this->_helper->_redirector('types');
        

    }

    /**
     * @brief Akcja delete category
     * 
     * Akcja usuwająca kategorię.
     * Usunięte mogą być tylko kategorie, które nie mają przypisanych do siebie
     * typów towarów. Akcja nie posiada własnego widoku.
     */
    public function deleteCategoryAction()
    {
        $id = $this->getRequest()->getParam('id');
        if(isset ( $id )){
            $typeMapper = new Application_Model_CommodityTypeMapper();
            
            if($typeMapper->count('Category_id = "'.$id.'"') == 0 ){
                $mapper = new Application_Model_CategoryMapper();
                $mapper->delete($id);
                $this->_helper->_flashMessenger->addMessage('success/Usunięto podaną kategorię');
            } else {
                $this->_helper->_flashMessenger->addMessage('error/Podana kategoria jest już w użyciu');
            }
        } else {
            $this->_helper->_flashMessenger->addMessage('error/Nie wskazano kategorii do usunięcia ');
        }
        $this->_helper->_redirector('categories');
    }
    
    /**
     * Akcja edit category
     * 
     * Akcja umożliwiająca zmianę nazwy kategorii.
     * W formularzu edycji automatycznie wprowadzana jest stara nazwa.
     */
    public function editCategoryAction()
    {
        $id = $this->getRequest()->getParam('id');
        $request = $this->getRequest();
        $form = new Application_Form_AddCategory();
        $this->view->form = $form;
        
        if(isset ( $id )){
            $mapper = new Application_Model_CategoryMapper();
            $cat = $mapper->find($id);
            $data = array(
            
            'name'          => $cat->getName(),
            
             );
            $form->populate($data);
            
            if($cat != NULL ){
                if($request->isPost()){
                    if($form->isValid($request->getPost())){
                        $cat->setOptions($form->getValues());
                        $mapper->save($cat);
                        $this->_helper->_flashMessenger->addMessage('success/Zmieniono nazwę kategorii');
                        $this->_helper->_redirector('categories'); 
                    }
                }
            } else {
                $this->_helper->_flashMessenger->addMessage('error/Nie znaleziono kategorii o podanym id');
                $this->_helper->_redirector('categories');      
            }
        } else {
            $this->_helper->_flashMessenger->addMessage('error/Nie wskazano kategorii do edycji ');
            $this->_helper->_redirector('categories');
        }
    }

    /**
     * @brief Metoda wykonywana po zakończeniu akcji. 
     * 
     * Dzięki niej wyświetlana jest stopka strony.
     */
    public function postDispatch()
    {
        $this->view->render('index/_footbox.phtml');
        
    }
    
    /**
     * @brief Metoda zmieniająca format daty na używany w formularzach (dd/MM/YYYY)
     * 
     * @param string $date
     * @return string 
     */
    private function changeDateFormat($date)
    {
        $date = new Zend_Date($date);
        return $date->toString('dd/MM/YYYY');
    }

}







